package com.lyc.api.service;

import com.lyc.api.VO.RankVO;
import com.lyc.common.model.BookInfo;
import com.lyc.common.model.Category;
import com.lyc.common.repository.BookInfoRepository;
import com.lyc.common.repository.CategoryRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by 廖师兄
 * 2017-05-26 21:52
 */
@Service
@Slf4j
public class BookService {

    private final static String HOST = "http://www.qisuu.com";

    @Autowired
    private BookInfoRepository bookInfoRepository;

    @Autowired
    private CategoryRepository categoryRepository;

    /**
     * 按照下载量排序
     * @param categoryId
     * @param page
     * @param size
     * @return
     */
    public List<BookInfo> list(Integer categoryId, Integer page, Integer size) {
        PageRequest pageRequest = new PageRequest(page, size);
        Page<BookInfo> bookInfoPage = bookInfoRepository.findByCategoryIdOrderByBookReadCountDesc(categoryId, pageRequest);
        log.info("bookInfoPage={}", bookInfoPage);

        if (bookInfoPage == null || bookInfoPage.getTotalPages() == 0) {
            return new ArrayList<>();
        }

        List<BookInfo> bookInfoList = bookInfoPage.getContent();
        this.dealBookInfoList(bookInfoList);

        return bookInfoList;
    }

    /**
     * 详情
     * @param bookId
     * @return
     */
    public BookInfo detail(String bookId) {
        BookInfo bookInfo = bookInfoRepository.findOne(bookId);
        if (bookInfo == null) {
            return null;
        }

        this.dealBookInfo(bookInfo);
        return bookInfo;
    }

    public List<BookInfo> searchByName(String bookName) {
        List<BookInfo> bookInfoList = bookInfoRepository.findTop50ByBookNameContainsOrderByBookReadCountDesc(bookName);
        this.dealBookInfoList(bookInfoList);
        return bookInfoList;
    }

    public List<BookInfo> searchByAuthor(String bookAuthor) {
        List<BookInfo> bookInfoList = bookInfoRepository.findTop50ByBookAuthorLikeOrderByBookReadCountDesc(bookAuthor);
        this.dealBookInfoList(bookInfoList);
        return bookInfoList;
    }

    public List<BookInfo> list(List<String> bookIdList) {
        List<BookInfo> bookInfoList = bookInfoRepository.findByBookIdIn(bookIdList);
        this.dealBookInfoList(bookInfoList);
        return bookInfoList;
    }

    /**
     * 查询每一个分类下的下载量排名前10条数据
     * @return
     */
    public List<RankVO> rank(Integer size) {

        //返回的结构
        List<RankVO> rankVOList = new ArrayList<>();

        //查询所有的分类
        List<Category> categoryList = categoryRepository.findAll();

        Map<Integer, List<Category>> mapCategoryId = categoryList.stream()
                .collect(Collectors.groupingBy(Category::getCategoryId));

        Map<Integer, List<Category>> map = categoryList.stream()
                .filter(category -> category.getCategoryParentId() != null)
                .collect(Collectors.groupingBy(Category::getCategoryParentId));

        for (Map.Entry<Integer, List<Category>> entry : map.entrySet()) {
            //拿到1级目录下所有的二级目录id
            List<Integer> integeList = entry.getValue().stream().map(e -> e.getCategoryId()).collect(Collectors.toList());
            List<BookInfo> bookInfoList = new ArrayList<>();
            for (Integer categoryId: integeList) {
                bookInfoList.addAll(bookInfoRepository.findTop10ByCategoryIdOrderByBookReadCountDesc(categoryId));
            }
            //排序, 获取前10条
            bookInfoList = bookInfoList.stream()
                    .sorted((o1, o2) -> o2.getBookReadCount().compareTo(o1.getBookReadCount()))
                    .limit(size)
                    .collect(Collectors.toList());

            //设置要返回的数据
            Category category = mapCategoryId.get(entry.getKey()).get(0);

            RankVO rankVO = new RankVO();
            rankVO.setCategoryId(category.getCategoryId());
            rankVO.setCategoryName(category.getCategoryName());
            this.dealBookInfoList(bookInfoList);
            rankVO.setBookInfoList(bookInfoList);

            rankVOList.add(rankVO);
        }

        return rankVOList;
    }

    /**
     * 阅读量+1
     * @return
     */
    public BookInfo increaseReadCount(BookInfo bookInfo) {
        bookInfo.setBookReadCount(bookInfo.getBookReadCount() + 1);
        return bookInfoRepository.save(bookInfo);
    }

    /**
     * 处理单本书
     * @param bookInfo
     */
    private void dealBookInfo(BookInfo bookInfo) {
        bookInfo.setBookImage(this.dealBookImage(bookInfo.getBookImage()));

        Category category = categoryRepository.findOne(bookInfo.getCategoryId());
        if (category != null) {
            bookInfo.setCategoryName(category.getCategoryName());
        }
    }

    private void dealBookInfoList(List<BookInfo> bookInfoList) {
        bookInfoList.stream().forEach(b -> {
            //处理nameImage
            b.setBookImage(this.dealBookImage(b.getBookImage()));
        });
    }

    /**
     * 处理书列表
     * @param bookInfoList
     */
    private void dealBookInfoList(List<BookInfo> bookInfoList, Boolean withCategory) {
        //增加categoryName字段
        List<Integer> integerList = bookInfoList.stream()
                .map(e -> e.getCategoryId())
                .collect(Collectors.toList());
        List<Category> categoryList = categoryRepository.findByCategoryIdIn(integerList);
        if (CollectionUtils.isEmpty(categoryList)) {
            return;
        }

        bookInfoList.stream().forEach(b -> {
            categoryList.stream().forEach(e -> {
                if (b.getCategoryId().equals(e.getCategoryId())) {
                    b.setCategoryName(e.getCategoryName());
                }
            });

            //处理nameImage
            b.setBookImage(this.dealBookImage(b.getBookImage()));
        });
    }

    private String dealBookImage(String path) {
        return HOST + path;
    }
}
